package com.learn.english.service.impl;


import com.learn.english.constants.CacheConstants;
import com.learn.english.constants.ChatConstants;
import com.learn.english.enums.TimeEnum;
import com.learn.english.mapper.ChatMessagesMapper;
import com.learn.english.mapper.ChatSessionMapper;
import com.learn.english.mapper.LLMMapper;
import com.learn.english.model.entity.ChatSession;
import com.learn.english.model.entity.KnowledgeBase;
import com.learn.english.model.param.ChatParameters;
import com.learn.english.model.param.Emitters;
import com.learn.english.model.param.Messages;
import com.learn.english.service.ILLMService;
import com.learn.english.service.RedisService;
import com.learn.english.utils.ChatUtil;
import com.learn.english.utils.GroupUtil;
import com.learn.english.utils.RetrievalUtils;
import java.util.concurrent.CompletableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author TISNIW
 * @version 1.0
 * @date 2025/6/16 11:12
 * @desc
 */
@Slf4j
@Service
public class LLMServiceImpl implements ILLMService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private ChatUtil chatUtil;

    @Autowired
    private ChatMessagesMapper messagesMapper;

    @Autowired
    private ChatSessionMapper sessionMapper;
    @Autowired
    private GroupUtil groupUtil;
    @Autowired
    private RetrievalUtils retrievalUtils;

    @Override
    public String chat(String model, String prompt, String sessionId, Boolean think) {
        // 1. 获取或创建会话参数
        ChatParameters parameters = redisService.getCacheObject(CacheConstants.AI_CHAT_SESSION_KEY + sessionId, ChatParameters.class);
        if (parameters == null) {
            // 如果没有缓存，则从数据库加载会话和消息
            String title = sessionMapper.getSession(sessionId);
            List<Messages> messages = messagesMapper.getChatParameters(sessionId);
            if (messages == null || messages.isEmpty()) {
                messages = new ArrayList<>();
            }
            messages.add(Messages.builder().role("user").content(prompt).build());
            parameters = ChatParameters.builder()
                    .model(model)
                    .messages(messages)
                    .think(think)
                    .stream(true)
                    .build();
            redisService.setCacheObject(CacheConstants.AI_CHAT_SESSION_KEY + sessionId, parameters, TimeEnum.THIRTY_MINUTE);
        } else {
            parameters.getMessages().add(Messages.builder().role("user").content(prompt).build());
            redisService.setCacheObject(CacheConstants.AI_CHAT_SESSION_KEY + sessionId, parameters, TimeEnum.THIRTY_MINUTE);
        }
        if (parameters.getMessages().size() < 2){
            log.error("sessionId:{} session is null", sessionId);
            sessionMapper.updateSession(sessionId, prompt.substring(0, 10));
        }

        log.info("LLM参数: {}", parameters);

        // 2. 存储用户消息到数据库
        messagesMapper.insertMessage(sessionId, "user", prompt);

        // 3. 构建增强后的用户请求
        String enhancedPrompt = createPrompt(prompt);

        // 4. 获取回复，使用增强后的prompt
        ChatParameters finalParameters = parameters;
        chatUtil.chatStream(model, enhancedPrompt, parameters.getMessages(), sessionId, think, () -> {
            // 异步生成会话标题
            if (finalParameters.getMessages().size() <= 2) { // 只有用户的第一条消息和AI的回复
                generateSessionTitle(model, sessionId, prompt);
            }
        });

        return sessionId;
    }



    /**
     * 创建新的会话
     *
     * @param userId 用户ID
     * @return 新会话ID
     */
    @Override
    public String newSession(Long userId) {
        String sessionId = UUID.randomUUID().toString().replace("-", "");
        String defaultTitle = "New Session";

        // 插入数据库
        sessionMapper.createSession(sessionId,userId, defaultTitle);

        // 可选：写入 Redis 缓存
        // redisService.setCacheObject(CacheConstants.AI_CHAT_SESSION_KEY + sessionId, ...)

        return sessionId;
    }

    /**
     * 获取用户所有会话列表
     *
     * @param userId 用户ID
     * @return JSON 格式的会话列表
     */
    @Override
    public List<ChatSession> listSession(Long userId) {
        List<ChatSession> sessions = sessionMapper.listSessionsByUserId(userId);
        // 这里可以使用 Jackson 或 Gson 序列化成 JSON
        return sessions;
    }

    /**
     * 删除指定会话
     *
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @return 删除结果
     */
    @Override
    public String deleteSession(Long userId, String sessionId) {
        sessionMapper.deleteSessionById(sessionId);

        // 同时删除消息记录
        messagesMapper.deleteMessagesBySessionId(sessionId);

        // 删除 Redis 缓存
        redisService.deleteObject(CacheConstants.AI_CHAT_SESSION_KEY + sessionId);

        return "Session deleted";
    }

    /**
     * 获取会话中的消息记录
     *
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @return 消息列表
     */
    @Override
    public List<Messages> getMessages(Long userId, String sessionId) {
        return messagesMapper.getChatParameters(sessionId);
    }
    /**
     * 生成会话标题
     * @param model 模型名称
     * @param sessionId 会话ID
     * @param userPrompt 用户的第一条消息
     */
    private void generateSessionTitle(String model, String sessionId, String userPrompt) {
        try {
            // 构建生成标题的提示
            String titlePrompt = "基于以下对话内容，生成一个20字以内的简洁标题：" + userPrompt;
            
            // 调用AI生成标题
            String generatedTitle = chatUtil.generateTitle(model, titlePrompt);
            
            // 确保标题在20字以内
            if (generatedTitle != null) {
                // 截断到20个字符
                String finalTitle = generatedTitle.length() > 20 
                    ? generatedTitle.substring(0, 20) 
                    : generatedTitle;
                
                // 更新会话标题
                sessionMapper.updateSession(sessionId, finalTitle);
                log.info("为会话 {} 生成标题: {}", sessionId, finalTitle);
            }
        } catch (Exception e) {
            log.error("生成会话标题失败: {}", e.getMessage());
        }
    }
    
    private String createPrompt(String prompt) {
        StringBuilder promptBuilder = new StringBuilder();
        Map<String,List<String>> graphKeywords = groupUtil.getGroupKey(prompt);
        String graphRetrieval = groupUtil.graphRetrieval(graphKeywords);
        List<KnowledgeBase> knowledgeBaseList = retrievalUtils.retrieveSimilarKnowledge(prompt);
        int i = 0;
        StringBuilder similarContent = new StringBuilder();
        if (knowledgeBaseList != null){

            for (KnowledgeBase similarKnowledge : knowledgeBaseList) {
                similarContent.append(similarKnowledge.getTitle() + "->" + similarKnowledge.getContent()).append("\n");
                log.info("相似知识库内容：{}", similarKnowledge.getContent());
            }
            i = 1;
        }
        if (graphRetrieval != null){
            i = 2;
        }
        if (knowledgeBaseList != null && !knowledgeBaseList.isEmpty()){
            i = 3;
        }
        switch (i) {
            case 1:
                promptBuilder
                        .append(ChatConstants.TEXT_PROMPT)
                        .append(similarContent);
                break;
            case 2:
                promptBuilder
                        .append(ChatConstants.GRAPH_PROMPT)
                        .append(graphRetrieval);
                break;
            case 3:
                promptBuilder
                        .append(ChatConstants.TEXT_PROMPT)
                        .append(similarContent)
                        .append(ChatConstants.GRAPH_PROMPT)
                        .append(graphRetrieval);
                break;
            default:
                break;
        }
        promptBuilder
                .append(ChatConstants.ORIGINAL_PROMPT)
                .append(prompt);
        log.info("promptBuilder:{}",promptBuilder.toString());
        return promptBuilder.toString();
    }
}